import os

from xml.etree import ElementTree

import pyglet

from gamelib import items, magic, character, abilities


class Party(object):
    '''
    Party attributes

    coins   -- the wealth the party has accumulated through encounters
    level   -- simply a count of the number of encounters the party has had
    '''
    def __init__(self, coins=0, level=1):
        self.characters = []
        self.items = []
        self.coins = coins
        self.level = level
        self.maps_seen = ['level-town-1.xml', 'level-dungeon-1.xml']

    def get(self, name):
        for c in self.characters:
            if c.name == name:
                return c
        return None

    def add(self, character):
        if [c for c in self.characters if c.name == character.name]:
            raise ValueError('character names must be unique in a party')
        self.characters.append(character)

    def save(self, directory):
        # generate the XML
        root = ElementTree.Element('party', coins=str(self.coins),
            level=str(self.level))
        root.tail = '\n'

        r = ElementTree.SubElement(root, 'maps-seen')
        r.tail = '\n'
        for map in self.maps_seen:
            s = ElementTree.SubElement(r, 'map')
            s.text = map

        r = ElementTree.SubElement(root, 'items')
        r.tail = '\n'
        for item in self.items:
            item.to_xml(r)

        r = ElementTree.SubElement(root, 'characters')
        r.tail = '\n'
        for character in self.characters:
            character.to_xml(r)

        tree = ElementTree.ElementTree(root)

        filename = os.path.join(directory, 'party.xml')
        tree.write(filename)

    @classmethod
    def load(cls, directory):
        tree = ElementTree.parse(os.path.join(directory, 'party.xml'))
        root = tree.getroot()
        p = cls(int(root.get('coins')), int(root.get('level')))

        p.items = [items.from_xml(tag) for tag in root.findall('items/item')]

        p.maps_seen = [tag.text for tag in root.findall('maps-seen/map')]

        p.characters = [PC.from_xml(tag)
            for tag in root.findall('characters/character')]
        return p

    @classmethod
    def create(cls, directory):
        p = cls()

        c = PC('male', 'fighter', 'Dodo', (1, 1), 'person-m-brown.png',
            strength = 7,
            dexterity = 6,
            constitution = 6,
            intelligence = 4,
            wisdom = 4,
            charisma = 7,
            max_health = 20,
            max_mana = 0,
            max_actions = 5,
            skills = dict(bashing=3, weapon_sword=4),
            abilities = [abilities.SuperStrike()],
        )
        p.add(c)
        p.lead = c
        c.body.equip(items.Sword())
        c.body.equip(items.Shield())
        c.body.equip(items.ChainMailTunic())
        c.body.equip(items.ChainMailKilt())
        c.body.equip(items.Shoes())

        c = PC('female', 'rogue', 'Dottie', (1, 1), 'person-f-green.png',
            strength = 5,
            dexterity = 7,
            constitution = 5,
            intelligence = 5,
            wisdom = 4,
            charisma = 6,
            max_health = 20,
            max_mana = 0,
            max_actions = 5,
            skills = dict(bashing=2, weapon_bow=4),
            carried = [items.Dagger()],
        )
        p.add(c)
        c.body.equip(items.Bow())
        c.body.equip(items.LeatherVest())
        c.body.equip(items.LeatherPants())
        c.body.equip(items.LeatherBoots())

        c = PC('male', 'wizard', 'Lodo', (1, 1), 'person-m-blue.png',
            strength = 4,
            dexterity = 5,
            constitution = 4,
            intelligence = 7,
            wisdom = 5,
            charisma = 5,
            max_health = 20,
            max_mana = 20,
            max_actions = 5,
            spells = [magic.EnergyBolt(), magic.FlameHands()],
            skills = dict(bashing=1, spell_attack=1, weapon_staff=3),
        )
        p.add(c)
        c.body.equip(items.Staff())
        c.body.equip(items.Robe())
        c.body.equip(items.Pants())
        c.body.equip(items.Shoes())

        c = PC('female', 'cleric', 'Lottie', (1, 1), 'person-f-purple.png',
            strength = 6,
            dexterity = 5,
            constitution = 6,
            intelligence = 4,
            wisdom = 7,
            charisma = 4,
            max_health = 20,
            max_mana = 20,
            max_actions = 5,
            spells = [magic.Heal()],
            skills = dict(bashing=2, spell_heal=1, weapon_mace=4),
        )
        p.add(c)
        c.body.equip(items.Mace())
        c.body.equip(items.ChainMailTunic())
        c.body.equip(items.Pants())
        c.body.equip(items.Shoes())


        p.items.extend([
            items.Shield(),
            items.Shield(),
            items.Shield(quality=.75),
            items.Sword(),
        ])

        # save it off
        p.save(directory)

        return p


class PC(character.Character):
    def friend_or_foe(self, other):
        '''Return boolean whether this character is on the same side as other.
        '''
        return isinstance(other, PC)

